﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Linq;
using IVisio = Microsoft.Office.Interop.Visio;
using SimpleVisio.Model;
using SimpleVisio.Util;
using System.Drawing;
using static SimpleVisio.Util.CoOrdinates;

namespace SimpleVisio
{
    class Program
    {
        //private static object shapeIndexRegistry;

        static void Main(string[] args)
        {
            try
            {
                AppConfigReader appconf = new AppConfigReader();
               SimpleVXMLreader vxml = new SimpleVXMLreader(appconf);

                // Console.WriteLine("Hello world");
                var app = new IVisio.Application();
                var docs = app.Documents;
                Point cursor = new Point(1,1);
                Dictionary<int, IVisio.Shape> shapeRegistry = new Dictionary<int, IVisio.Shape>();
                Dictionary<int, dynamic> shapeIndexRegistry = new Dictionary<int, dynamic>();

                // Create a new OrgChart using the org chart template
                //var doc = docs.AddEx("NaP.vst", IVisio.VisMeasurementSystem.visMSUS, 0, 0);
                //var doc = docs.AddEx(@"C:\Program Files (x86)\Microsoft Office\root\Office16\Visio Content\1033\NaP.vstx", IVisio.VisMeasurementSystem.visMSUS, 0, 0);
                //var doc = docs.AddEx(@"C:\Manoj\SimpleVisio\SimpleVisio\SimpleVisio\SimpleVisioStyles.vstx", IVisio.VisMeasurementSystem.visMSUS, 0, 0);                

                var doc = docs.AddEx(appconf.STARTTEMPLATE, IVisio.VisMeasurementSystem.visMSUS, 0, 0);
                //NaP.vssx
                var page = app.ActivePage;

                // Get the masters
               // bool is_visio_2013 = app.Version.StartsWith("15.");
                var orgchart_masters = doc.Masters;
                //var position_master = orgchart_masters["Server"];
                //var dyncon = orgchart_masters["Dynamic Connector"];

                //// three masters to drop
                //var masters = new object[]{ position_master, position_master, position_master };
                //// three coordinates to make the drop
                //var xy_array = new double[] { 1, 2, 3, 5, 6, 2 };

                // perform the drop of all shapes at once
                // and get the shape ids back out
                System.Array shape_ids_sa;
                //page.DropContainer()
                Direction x = (Direction)1;

                ////container.
                //var activewindow = app.ActiveWindow;
                //short selectargs = (short)IVisio.VisSelectArgs.visSelect;


                //page.DropManyU(masters, xy_array, out shape_ids_sa);
                //var shape_ids = (short[])shape_ids_sa;

                //// using the shape ids, get the shape objects
                //var shape0 = page.Shapes.ItemFromID16[shape_ids[0]];
                //shape0.Text = "Manoj";
                //var shape1 = page.Shapes.ItemFromID16[shape_ids[1]];
                //shape1.Text = "Prasadh";
                //var shape2 = page.Shapes.ItemFromID16[shape_ids[2]];
               // var container = 1;
                foreach (Container myContainer in vxml.visioContainers)
                {
                    List<object> myMastersList = new List<object>();
                    List<double> my_xy_array_List = new List<double>();
                    //var myMastersList[] = new object[myContainer.components.Count]();
                    int count = 0;
                    foreach (Component myComponent in myContainer.components)
                    {
                        count++;
                        string type = "Server";
                        if (myComponent.type.Length > 0) type = myComponent.type;
                        var my_position_master = orgchart_masters[type];
                        myMastersList.Add(my_position_master);
                        my_xy_array_List.Add(cursor.X);//, cursor.Y);
                        my_xy_array_List.Add(cursor.Y);//, cursor.Y);
                        x = (Direction)Math.Abs((int)x - 1);
                        if(appconf.CustomXY)
                        {
                            cursor = myComponent.myPoint;
                        }
                        else
                        {
                            cursor = Util.CoOrdinates.getNextPoint(cursor, x);
                        }
                    }
                    if (count > 0)
                    {
                        var mymasters = myMastersList.ToArray();
                        var my_xy_array = my_xy_array_List.ToArray();
                        //var container = getContainer(app, docs, "basic_u.vss", appconf.containerShape);
                        //container.

                        System.Array my_shape_ids_sa;
                        page.DropManyU(mymasters, my_xy_array, out my_shape_ids_sa);
                        var my_shape_ids = (short[])my_shape_ids_sa;
                        int shape_index = 0;

                        var myactivewindow = app.ActiveWindow;
                        short myselectargs = (short)IVisio.VisSelectArgs.visSelect;

                        foreach (Component myComponent in myContainer.components)
                        {
                            // using the shape ids, get the shape objects
                            var shape_current = page.Shapes.ItemFromID16[my_shape_ids[shape_index++]];
                            shape_current.Text = myComponent.name;
                            myComponent.shape = shape_current;
                            myContainer.index = ((dynamic)shape_current).Index;
                            shapeRegistry.Add(myComponent.id, myComponent.shape);
                            shapeIndexRegistry.Add(myComponent.id, ((dynamic)shape_current).Index);
                            myactivewindow.Select(shape_current, myselectargs);

                            //var shape1 = page.Shapes.ItemFromID16[shape_ids[1]];
                            //shape1.Text = "Prasadh";
                            //var shape2 = page.Shapes.ItemFromID16[shape_ids[2]];
                        }
                        if (myContainer.enabled)
                        {
                            //container = myContainer;
                            var container = getContainer(app, docs, appconf.BASICVSS, appconf.containerShape);

                            page.DropContainer(container, myactivewindow.Selection);

                            IVisio.Shape mycontainershape = page.Shapes[ ((dynamic)container).Index];
                            mycontainershape.Text = myContainer.name;
                            myContainer.shape = mycontainershape;
                            myContainer.index = ((dynamic)container).Index;
                            shapeRegistry.Add(myContainer.id, myContainer.shape);
                            shapeIndexRegistry.Add(myContainer.id, ((dynamic)container).Index);
                        }
                            myactivewindow.DeselectAll();
                    }
                }


                foreach (Container myContainer in vxml.visioContainers)
                {
                    int count = 0;
                    foreach (Component myComponent in myContainer.components)
                    {
                        foreach (Connector myConnector in myComponent.connectors)
                        {
                            var dyncon = orgchart_masters["Dynamic Connector"];
                            IVisio.Shape shape0 = shapeRegistry[myComponent.id];// myComponent.shape;
                            IVisio.Shape shape1 = shapeRegistry[myConnector.id];

                          //  IVisio.Shape shape0 = page.Shapes[shapeIndexRegistry[myComponent.id]];// myComponent.shape;
                          //  IVisio.Shape shape1 = page.Shapes[shapeIndexRegistry[myConnector.id]]; //shapeIndexRegistry[myConnector.id];

                            
                            //shape0.AutoConnect(shape1, IVisio.VisAutoConnectDir.visAutoConnectDirNone, dyncon);
                            IVisio.Shape connector = page.Drop(app.ConnectorToolDataObject, 4, 4);
                            connector.Text = myConnector.name;// "Connecting";
                            ConnectShapes(shape0, shape1, connector);
                        }
                    }
                    foreach (Connector myConnector in myContainer.connectors)
                    {
                        var dyncon = orgchart_masters["Dynamic Connector"];
                      //  IVisio.Shape shape0 = page.Shapes[shapeIndexRegistry[myContainer.id]];// myComponent.shape;
                      //  IVisio.Shape shape1 = page.Shapes[shapeIndexRegistry[myConnector.id]]; //shapeIndexRegistry[myConnector.id];

                        IVisio.Shape shape0 = shapeRegistry[myContainer.id];//myContainer.shape;
                        IVisio.Shape shape1 = shapeRegistry[myConnector.id];
                        //shape0.AutoConnect(shape1, IVisio.VisAutoConnectDir.visAutoConnectDirNone, dyncon);
                        IVisio.Shape connector = page.Drop(app.ConnectorToolDataObject, 2, 2);
                        connector.Text = myConnector.name;// "Connecting";
                        ConnectShapes(shape0, shape1, connector);
                    }
                }
                        // perform connections using the Dynamic Connection master

                        //activewindow.Select(shape0, selectargs);
                        //activewindow.Select(shape1, selectargs);
                        //page.DropContainer(container, activewindow.Selection);
                        //page.DropContainer(container, null);
                        //IVisio.Shape containershape = page.
                        int k = page.Shapes.Count;
                // IVisio.Shape containershape = page.Shapes.ItemU[((dynamic)container).UniqueID]; // .ItemFromUniqueID[container.UniqueID];

                //IVisio.Shape containershape = page.Shapes[((dynamic)container).Index]; // .ItemFromUniqueID[container.UniqueID];

                //containershape.Text = "Manojprasadh";

                //shape2.AutoConnect(containershape, IVisio.VisAutoConnectDir.visAutoConnectDirNone, dyncon);
                //IVisio.Shape connector = page.Drop(app.ConnectorToolDataObject, 2, 2);
                //connector.Text = "Connecting";



                //ConnectShapes(shape2, containershape, connector);

                //shape0.AutoConnect(shape1, IVisio.VisAutoConnectDir.visAutoConnectDirNone, dyncon);
                //container.a
                //container.ConnectionsAdded = null;
                //IVisio.Connect 
                //page.AutoConnectMany(ref shape2,ref container, 0);
                //shape2.Connects.
            }
            catch (Exception e)
            {

            }
        }

        private static IVisio.Master getContainer(IVisio.Application app, IVisio.Documents docs, string vss, string containerShape)
        {
            short flags = (short)
              (IVisio.VisOpenSaveArgs.visOpenDocked |
               IVisio.VisOpenSaveArgs.visOpenRO);
            var basic_stencil = docs.OpenEx("basic_u.vss", flags);
            var basic_masters = basic_stencil.Masters;
            var rounded_rect_master = basic_masters["Rounded Rectangle"];

            var stenciltype = IVisio.VisBuiltInStencilTypes.visBuiltInStencilContainers;

            var measurementsys = IVisio.VisMeasurementSystem.visMSDefault;
            short containeropenflags = (short)IVisio.VisOpenSaveArgs.visOpenHidden;
            string containerstencil_filename = app.GetBuiltInStencilFile(stenciltype, measurementsys);
            var container_stencil = docs.OpenEx(containerstencil_filename, containeropenflags);
            var containermasters = container_stencil.Masters;
            foreach (var v in containermasters)
            {
                //var vv = v.Name;
            }
            return containermasters["Plain"];
        }

        private static void ConnectShapes(IVisio.Shape shape1, IVisio.Shape shape2, IVisio.Shape connector)
        {
            // get the cell from the source side of the connector

            IVisio.Cell beginXCell = connector.get_CellsSRC(

            (short)IVisio.VisSectionIndices.visSectionObject,

            (short)IVisio.VisRowIndices.visRowXForm1D,

            (short)IVisio.VisCellIndices.vis1DBeginX);

            // glue the source side of the connector to the first shape

            beginXCell.GlueTo(shape1.get_CellsSRC(

            (short)IVisio.VisSectionIndices.visSectionObject,

            (short)IVisio.VisRowIndices.visRowXFormOut,

            (short)IVisio.VisCellIndices.visXFormPinX));

            // get the cell from the destination side of the connector

            IVisio.Cell endXCell = connector.get_CellsSRC(

            (short)IVisio.VisSectionIndices.visSectionObject,

            (short)IVisio.VisRowIndices.visRowXForm1D,

            (short)IVisio.VisCellIndices.vis1DEndX);

            // glue the destination side of the connector to the second shape

            endXCell.GlueTo(shape2.get_CellsSRC(

            (short)IVisio.VisSectionIndices.visSectionObject,

            (short)IVisio.VisRowIndices.visRowXFormOut,

            (short)IVisio.VisCellIndices.visXFormPinX));

        }
    }
}
